/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rules;

import types.ColoringInfo;
import types.ISudokuMatrix;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import utils.RuleHelper;


/**
 *
 * @author kostja
 */
public class RowInTwoQuadratCompleteOrClosedAndTwoFieldsClosed implements Rule {
    int quadrat = 0;

    public void setQuadrat(int x, int y) throws Exception {
        this.quadrat = RuleHelper.calculateQuadratNumber(x, y);
    }

    public int getQuadrat() {
        return this.quadrat;
    }

    public String getName() {
        return RowInTwoQuadratCompleteOrClosedAndTwoFieldsClosed.class.getSimpleName();
    }

    public String getDesc() {
        return "RowInTwoQuadratCompleteOrClosedAndTwoFieldsClosed ";
    }

    public boolean isApplicable(int row, int col, ISudokuMatrix matrix) {
        //System.out.println("Trying to apply rule "+ this.getName()+ " for "+row+","+col);
            boolean neighbour1IsComplete=false;
            boolean neighbour2IsComplete=false;
            boolean firstFieldIsClosed=false;
            boolean secondFieldIsClosed=false;
            int digit;
            try{
            this.setQuadrat(row, col);
            Collection candidat = RuleHelper.getMissingdigitsInQuadratOrColOrRow(RuleHelper.getDigittsSameRowAsCollection(row, matrix)); //liefert alle Zahlen die in der Zeile noch fehlen
            Collection digitsInQuadrat=RuleHelper.getDigitsSameQuadrat(row, col, matrix);
            Collection tempList;
            Iterator iter;
            int rowNeighbours1;
            int rowNeighbours2;
            candidat.removeAll(digitsInQuadrat);
            if(candidat.size()==1)
                return true;
            if(candidat.size()==0)
                return false;
            Iterator iterNeighbours=RuleHelper.getHorizontalQuadratNeighbours(RuleHelper.calculateQuadratNumber(row, col)).iterator();
            int neighbourQ1=(Integer)iterNeighbours.next();
            if(RuleHelper.isRowInQuadratComplete(neighbourQ1, row, matrix))
                neighbour1IsComplete=true;

            int neighbourQ2=(Integer)iterNeighbours.next();
            if(RuleHelper.isRowInQuadratComplete(neighbourQ2, row, matrix))
                neighbour2IsComplete=true;
            if (neighbour1IsComplete){
                tempList=RuleHelper.cloneCollection(candidat);
                iter=candidat.iterator();
                while(iter.hasNext()){
                    int a=(Integer)iter.next();
                    if(!(RuleHelper.isQuadratClosedForThisDigit(neighbourQ2,a,matrix)))
                        tempList.remove(a);
                }
                iter=tempList.iterator();
                while(iter.hasNext()){
                    digit=(Integer)iter.next();
                    Collection collRowNeighbours=RuleHelper.getRowNeighboursInTheSameQuadrat(RuleHelper.calculateQuadratNumber(row, col),col);
                    iter=collRowNeighbours.iterator();
                    rowNeighbours1=(Integer)iter.next();
                    rowNeighbours2=(Integer)iter.next();
                    if(!(RuleHelper.isFieldEmpty(row,rowNeighbours1,matrix)) && !(RuleHelper.isFieldEmpty(row,rowNeighbours2,matrix))) // falls beide Felder schon belegt sind
                        return true;
                    if((!(RuleHelper.isFieldEmpty(row,rowNeighbours1,matrix))) || (RuleHelper.existsDigitInCol(digit, rowNeighbours1, matrix))) // falls Feld_1 belegt oder gesperrt ist
                        firstFieldIsClosed=true;
                    if((!(RuleHelper.isFieldEmpty(row,rowNeighbours2,matrix))) || (RuleHelper.existsDigitInCol(digit, rowNeighbours2, matrix))) // falls Feld_2 belegt oder gesperrt ist
                        secondFieldIsClosed=true;
                    if (firstFieldIsClosed && secondFieldIsClosed)
                        return true;
                }
            }

        }catch (Exception ex) {
            Logger.getLogger(RowInTwoQuadratCompleteOrClosedAndTwoFieldsClosed.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    public int getWeight(int QuadratNumber) {
        return 100;
    }

    public int compareTo(Rule o) {
        if (this.getWeight(this.getQuadrat())<o.getWeight(o.getQuadrat()))
            return -1;
        else if (this.getWeight(this.getQuadrat())>o.getWeight(o.getQuadrat()))
            return 1;
        else
            return 0;
    }

    public ColoringInfo getCheckedUnits(int x, int y, ISudokuMatrix matrix) {
        throw new UnsupportedOperationException("Not supported yet.");
    }


}
